package com.obas.business.element.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.ClassUtils;

import com.ease.cache.Cache;
import com.ease.common.util.FileUtil;
import com.ease.common.util.JsonUtil;
import com.ease.dao.util.DataAccessObjectUtil;
import com.ease.platform.authorization.service.impl.AbstractAuthorizationServiceImpl;
import com.obas.access.business.service.CustomerAccessService;
import com.obas.access.business.service.DeviceAccessService;
import com.obas.access.business.service.DeviceMacAddressAccessService;
import com.obas.business.element.service.ElementLoaderManagementService;
import com.obas.business.element.vo.DeviceMacAddressDefinition;
import com.obas.integration.element.loader.DeviceMacAddressLoader;
import com.obas.integration.element.telnet.loader.HWMA5616TelnetDeviceMacAddressLoader;
import com.obas.model.business.Customer;
import com.obas.model.business.Device;
import com.obas.model.business.DeviceMacAddress;

@Deprecated
public class ElementLoaderManagementServiceImpl extends AbstractAuthorizationServiceImpl implements ElementLoaderManagementService {

	// private Map<String, DeviceMacAddressDefinition> elementMacAddressDefinitions;
	private static final transient Log log = LogFactory.getLog(ElementLoaderManagementServiceImpl.class);

	public static final String DEFINITION_FILE_NAME = DeviceMacAddressDefinition.class.getSimpleName() + ".json";

	private Cache cache;

	private DeviceAccessService deviceAccessService;

	private CustomerAccessService customerAccessService;

	private DeviceMacAddressAccessService deviceMacAddressAccessService;

	// private NetworkTopologyManagementService networkTopologyManagementService;

	public void init() {
		List<DeviceMacAddressDefinition> elementMacAddressDefinitions = getDeviceMacAddressDefinitions();

		if (notEmpty(elementMacAddressDefinitions)) {
			for (DeviceMacAddressDefinition elementMacAddressDefinition : elementMacAddressDefinitions) {
				cache.put(elementMacAddressDefinition.getEquipmentModelCode(), elementMacAddressDefinition);
			}
		}
	}

	public List<DeviceMacAddressDefinition> getDeviceMacAddressDefinitions() {

		String definitions = FileUtil.readClassPathResourceToString(ElementLoaderManagementServiceImpl.class, DEFINITION_FILE_NAME);
		if (null == definitions) {
			ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

			InputStream inputStream = classLoader.getResourceAsStream(ClassUtils.classPackageAsResourcePath(ElementLoaderManagementServiceImpl.class) + "/" + DEFINITION_FILE_NAME);
			try {
				definitions = IOUtils.toString(inputStream, "UTF-8");
			} catch (IOException e) {
				log.error("DEFINITION_FILE_NAME=" + DEFINITION_FILE_NAME, e);
			}

		}
		return JsonUtil.unmarshalList(definitions, DeviceMacAddressDefinition.class);
	}

	public DeviceMacAddressDefinition getByEquipmentModelCode(final String equipmentModelCode) {
		DeviceMacAddressDefinition elementMacAddressDefinition = (DeviceMacAddressDefinition) cache.get(equipmentModelCode);

		return elementMacAddressDefinition;
	}

	public List<DeviceMacAddress> loadDeviceMacAddressByDevice(Device device) {

		String equipmentModelCode = device.getEquipmentModelCode();
		init();
		DeviceMacAddressDefinition elementMacAddressDefinition = getByEquipmentModelCode(equipmentModelCode);
		if (null != elementMacAddressDefinition) {
			DeviceMacAddressLoader deviceMacAddressRetriever = null;

			try {
				try {
					deviceMacAddressRetriever = (DeviceMacAddressLoader) Class.forName(elementMacAddressDefinition.getDeviceMacAddressLoaderClass()).newInstance();
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}

				if (null != deviceMacAddressRetriever) {
					deviceMacAddressRetriever.setEquipmentModelCode(equipmentModelCode);

					deviceMacAddressRetriever.setHost(device.getNmIpAddress());
					deviceMacAddressRetriever.setPort(23);
					deviceMacAddressRetriever.setUsername(device.getTelnetUsername());
					deviceMacAddressRetriever.setPassword(device.getTelnetPassword());

					deviceMacAddressRetriever.setUsernamePrompt(elementMacAddressDefinition.getUsernamePrompt());
					deviceMacAddressRetriever.setPasswordPrompt(elementMacAddressDefinition.getPasswordPrompt());
					deviceMacAddressRetriever.setMorePrompt(elementMacAddressDefinition.getMorePrompt());
					deviceMacAddressRetriever.setCommand(elementMacAddressDefinition.getCommand());
				}

				return deviceMacAddressRetriever.loadDeviceMacAddress();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	public void loadDeviceMacAddress(List<Device> devices) {

		long[] deviceIds = DataAccessObjectUtil.idOf(devices);
		if (notEmpty(deviceIds)) {
			devices = deviceAccessService.findByIds(deviceIds);
			// } else {
			// devices = deviceAccessService.findAll();
		}

		if (notEmpty(devices)) {
			for (Device device : devices) {

				List<DeviceMacAddress> deviceMacAddresses = loadDeviceMacAddressByDevice(device);

				if (null != deviceMacAddresses) {
					for (DeviceMacAddress deviceMacAddress : deviceMacAddresses) {
						deviceMacAddress.setDeviceCode(device.getCode());
						deviceMacAddress.setDeviceId(device.getId());
						deviceMacAddress.setEnabled(false);
						deviceMacAddressAccessService.create(deviceMacAddress);

						String macAddress = deviceMacAddress.getMacAddress();

						Customer account = customerAccessService.findOneByMacAddress(macAddress);
						if (null == account) {
							account = new Customer();
							account.setName("[" + macAddress + "]");
							account.setMacAddress(macAddress);
							customerAccessService.create(account);
						}
					}

				}
			}
		}

		// networkTopologyManagementService.generateNetworkTopology();
	}

	/**
	 * @return the deviceMacAddressAccessService
	 */
	public DeviceMacAddressAccessService getDeviceMacAddressAccessService() {
		return deviceMacAddressAccessService;
	}

	/**
	 * @param deviceMacAddressAccessService
	 *            the deviceMacAddressAccessService to set
	 */
	public void setDeviceMacAddressAccessService(DeviceMacAddressAccessService deviceMacAddressAccessService) {
		this.deviceMacAddressAccessService = deviceMacAddressAccessService;
	}

	/**
	 * @return the deviceAccessService
	 */
	public DeviceAccessService getDeviceAccessService() {
		return deviceAccessService;
	}

	/**
	 * @param deviceAccessService
	 *            the deviceAccessService to set
	 */
	public void setDeviceAccessService(DeviceAccessService deviceAccessService) {
		this.deviceAccessService = deviceAccessService;
	}

	/**
	 * @return the customerAccessService
	 */
	public CustomerAccessService getCustomerAccessService() {
		return customerAccessService;
	}

	/**
	 * @param customerAccessService
	 *            the customerAccessService to set
	 */
	public void setCustomerAccessService(CustomerAccessService customerAccessService) {
		this.customerAccessService = customerAccessService;
	}

	public static void main(String[] args) {
		DeviceMacAddressDefinition elementMacAddressDefinition = new DeviceMacAddressDefinition();
		elementMacAddressDefinition.setDeviceMacAddressLoaderClass(HWMA5616TelnetDeviceMacAddressLoader.class.getName());
		System.out.print(JsonUtil.marshal(elementMacAddressDefinition));
	}

	/**
	 * @return the cache
	 */
	public Cache getCache() {
		return cache;
	}

	/**
	 * @param cache
	 *            the cache to set
	 */
	public void setCache(Cache cache) {
		this.cache = cache;
	}
}
